﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK;
using System.Drawing;
using System.Windows.Forms;
using OpenTK.Graphics.OpenGL;

// Opengl problem with inverted Y: motherfuckers
// We always use

namespace NLE
{
    static class Extensions
    {
        public static Vector2 InvertY(this Vector2 pVector)
        {
            return new Vector2(pVector.X, -pVector.Y);
        }

        public static Vector2 InvertX(this Vector2 pVector)
        {
            return new Vector2(-pVector.X, pVector.Y);
        }

        public static Vector3 InvertY(this Vector3 pVector)
        {
            return new Vector3(pVector.X, -pVector.Y, pVector.Z);
        }

        public static Vector3 InvertX(this Vector3 pVector)
        {
            return new Vector3(-pVector.X, pVector.Y, pVector.Z);
        }

        public static bool HasPointInside(this LevelObject pLevelObject, Point P, ImageControl pControl)
        {
            int pX = (int)((float)(P.X - (int)pLevelObject.Position.X + (int)pLevelObject.Origin.X));
            int pY = (int)((float)(-(P.Y - (int)pLevelObject.Position.Y - (int)pLevelObject.Origin.Y)));

            if (pX > 50 && pX < (pControl.TextureLibrary[pLevelObject.TextureName].Texture.w - 1) &&
                pY > 50 && pY < (pControl.TextureLibrary[pLevelObject.TextureName].Texture.h - 1))
            {
                int lol = 5;
            }





            Vector2 mousePoint = new Vector2((float)P.X, (float)P.Y);

            Vector2 originOfObject = new Vector2(pLevelObject.Origin.X, -pLevelObject.Origin.Y);

            Vector2 position = pLevelObject.Position;


            // Make a vector from middle of object to the mouse (|ab| = b - a)
            Vector2 positionToMouse = mousePoint - position;



            // Rotate this vector
            Vector3 tempVector = new Vector3(positionToMouse.X, positionToMouse.Y, 0);
            Matrix4 tR = Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(-pLevelObject.Rotation));
            tempVector = Vector3.Transform(tempVector, tR);
            positionToMouse = new Vector2(tempVector.X, tempVector.Y);

            Vector2 upperLeftCorner = position - originOfObject;

            Vector2 newMouse = position + positionToMouse;

            Vector2 pixelResult = newMouse - upperLeftCorner;
            pixelResult = new Vector2(pixelResult.X, -pixelResult.Y);
            // Subtract origin to go to upper left corner


            // We have to rotate the vector to simulate rotating normals
            //Vector3 tempVector = new Vector3(pX, pY, 0);

            //int tw = pControl.TextureLibrary[pLevelObject.TextureName].Texture.w;
            //int th = pControl.TextureLibrary[pLevelObject.TextureName].Texture.h;





            pX = (int)pixelResult.X;
            pY = (int)pixelResult.Y;

            pX = Math.Min(pX, pControl.TextureLibrary[pLevelObject.TextureName].Texture.w - 1);
            pX = Math.Max(pX, 0);
            pY = Math.Min(pY, pControl.TextureLibrary[pLevelObject.TextureName].Texture.h - 1);
            pY = Math.Max(pY, 0);

            return Functions.Embeds(P.X,
                P.Y,
                (int)((pLevelObject.Position.X - pLevelObject.Origin.X)),
                (int)((pLevelObject.Position.Y + pLevelObject.Origin.Y)),
                (int)((float)pControl.TextureLibrary[pLevelObject.TextureName].Texture.w * pLevelObject.Scale.X),
                (int)((float)pControl.TextureLibrary[pLevelObject.TextureName].Texture.h * pLevelObject.Scale.Y))
                && pControl.TextureLibrary[pLevelObject.TextureName].Texture.bitmap.GetPixel(pX, pY).A != 0;
        }

        public static bool HasMouseInside(this LevelObject pLevelObject, ImageControl pControl)
        {
            Point P = Functions.GetMouseToScreenCoords(pControl);

            return HasPointInside(pLevelObject, P, pControl);

        }

        public static void DrawAt(this Texture2D pTexture, Control pControl, Vector2 pPosition, float pRotation, Vector2 pScale, Vector2 pOrigin, Color pColor)
        {


            GL.MatrixMode(MatrixMode.Modelview);
            Matrix4 r = Camera.Instance.Transformation;
            GL.LoadMatrix(ref r);

            GL.Color4(pColor);

            pTexture.blending = true;
            //pTexture.SetBlending(255, 255, 255, 

            pTexture.origin = true;

            Vector2.Multiply(ref pOrigin, ref pScale, out pOrigin);

            Vector2 tempOrigin = pOrigin;


            pPosition = new Vector2(pPosition.X - pOrigin.X, pPosition.Y + pOrigin.Y);


            pTexture.originX = (int)(pPosition.X + pOrigin.X);
            pTexture.originY = (int)(pPosition.Y - pOrigin.Y);



            pTexture.rotation = pRotation;


            // Position is in world space, we take care of the transformation
            pTexture.Draw(
                (int)pPosition.X, 
                (int)pPosition.Y, 
                (int)((float)pTexture.w * pScale.X), 
                (int)((float)pTexture.h * pScale.Y));

        }

    }
}
